import 'dart:math';
import 'dart:ui';

abstract class PreviewActionScript {
  int _index = 0;
  int currentUseColorIndex = 0;
  bool order = false;
  ///maxIndex 完整播放完需要多少次，在同一脚本循环播放多个脚本时要用到（例：91 7彩 波浪,同步呼吸）
  /// -1代表无限制
  int maxIndex;
  final List<int> _fgColors;
  final List<int> _bgColors;

  Duration duration;
  Duration transformDuration;

  PreviewActionScript({bgColors, fgColors,this.duration ,this.transformDuration,this.maxIndex = -1})
      : _bgColors = bgColors ?? [],
        _fgColors = fgColors ?? [];

  List<Color> getColorList();

  int get index => _index;
}

///异步随机模式
class RandomAsyncScript extends PreviewActionScript {
  RandomAsyncScript(List<int> bgColors, {Duration duration, Duration transformDuration}) : super(bgColors: bgColors,duration: duration,transformDuration: transformDuration);

  @override
  List<Color> getColorList() {
    if (_bgColors.length > 0) {
      List<Color> list = [];
      for (int i = 0; i < 12; i++) {
        list.add(Color(_bgColors[Random().nextInt(_bgColors.length)]));
      }
      _index++;
      return list;
    }
    return null;
  }

  @override

  int get maxIndex => -1;
}

///星星闪烁
class StarsTwinkleScript extends PreviewActionScript {
  StarsTwinkleScript(List<int> bgColors) : super(bgColors: bgColors);

  @override
  List<Color> getColorList() {
    if (_bgColors.length > 0) {
      List<Color> list = [];
      for (int i = 0; i < 12; i++) {
        list.add(Color(_bgColors[Random().nextInt(_bgColors.length)]));
      }
      _index++;
      return list;
    }
    return null;
  }
}

///对闪模式
class MutualFlashScript extends PreviewActionScript {
  MutualFlashScript(List<int> bgColors) : super(bgColors: bgColors);

  @override
  List<Color> getColorList() {
    if (_bgColors.length > 0) {
      List<Color> list = [];
      for (int i = 0; i < 12; i++) {
        // list.add(Color(_bgColors[Random().nextInt(_bgColors.length)]));
        if (order == true) {
          if (i % 2 != 0) {
            list.add(Color(_bgColors[0]));
          } else {
            list.add(Color(_bgColors[1]));
          }
        } else {
          if (i % 2 != 0) {
            list.add(Color(_bgColors[1]));
          } else {
            list.add(Color(_bgColors[0]));
          }
        }
      }
      order = !order;
      _index++;
      return list;
    }
    return null;
  }
}

///波浪模式
class WaveScript extends PreviewActionScript {
  List<Point> _indexList = [
    Point(0, 7),
    Point(3, 6),
    Point(2, 9),
    Point(10, 5),
    Point(8, 11),
    Point(4, 1)
  ];

  WaveScript(List<int> bgColors, List<int> fgColors,{Duration duration,Duration transformDuration})
      : super(bgColors: bgColors, fgColors: fgColors,duration: duration,transformDuration: transformDuration,maxIndex: fgColors.length);

  @override
  List<Color> getColorList() {
    if (_index == _fgColors.length) {
      _index = 0;
    }

    List<Color> list = [];
    for (int i = 0; i < 12; i++) {
      list.add(Color(_bgColors[0]));
    }
    for (int i = 0; i < 12; i++) {
      if (i == _indexList[_index].x || i == _indexList[_index].y) {
        list[_indexList[_index].x] = Color(_fgColors[_index]);
        list[_indexList[_index].y] = Color(_fgColors[_index]);
      }
    }

    _index++;

    return list;
  }
}

///同步呼吸
class SynchronizedBreathScript extends PreviewActionScript {
  SynchronizedBreathScript(List<int> fgColors,{Duration duration,Duration transformDuration})
      : super(fgColors: fgColors,duration: duration,transformDuration: transformDuration,maxIndex: fgColors.length);

  @override
  List<Color> getColorList() {
    if (_index == _fgColors.length) {
      _index = 0;
    }
    List<Color> list = [];

    for (int i = 0; i < 12; i++) {
      list.add(Color(_fgColors[_index]));
    }
    _index++;


    return list;
  }
}

///同步频闪
class SynchronousStrobeScript extends PreviewActionScript {
  SynchronousStrobeScript(List<int> fgColors,{Duration duration,Duration transformDuration})
      : super(fgColors: fgColors,duration: duration,transformDuration: transformDuration,maxIndex: fgColors.length);

  @override
  List<Color> getColorList() {
    if (_index == _fgColors.length) {
      _index = 0;
    }

    List<Color> list = [];

    for (int i = 0; i < 12; i++) {
      list.add(Color(_fgColors[_index]));
    }
    _index++;

    return list;
  }
}

///同步跳变
class SynchronousJumpScript extends PreviewActionScript {
  List<Color> allFgColor;
  SynchronousJumpScript(List<int> fgColors) : super(fgColors: fgColors,maxIndex: fgColors.length*2){
    allFgColor = List.generate(fgColors.length*2, (index){
      if(index%2!=0){
        return Color(0xff000000);
      }else{
        return Color(_fgColors[index~/2]);
      }
    });
  }


  @override
  List<Color> getColorList() {

    if (_index == allFgColor.length) {
      _index = 0;
    }

    List<Color> list = [];

    for (int i = 0; i < 12; i++) {
      list.add(allFgColor[_index]);
    }
    _index++;

    return list;
  }
}

///填充并还原
class ColorFillScript extends PreviewActionScript {
  List<Point> _indexList = [
    Point(0, 7),
    Point(3, 6),
    Point(2, 9),
    Point(10, 5),
    Point(8, 11),
    Point(4, 1)
  ];
  List<Color> colors;
  Color firstFillColor;
  Color secondFillColor;
  Color firstBgColor;
  Color secondBgColor;
  bool needReturn;
  bool _isBack = false;

  ColorFillScript(this.firstBgColor, this.secondBgColor, this.firstFillColor,
      this.secondFillColor,
      {this.needReturn = false});

  @override
  List<Color> getColorList() {
    if (colors == null) {
      colors = getInitColors();
      return colors;
    } else {
      if (_isBack) {
        colors[_indexList[_index].x] = firstBgColor;
        colors[_indexList[_index].y] = secondBgColor;
        if (_index <= 0) {
          _isBack = false;
        } else {
          _index--;
        }
      } else {
        if (_index > 5) {
          if (needReturn) {
            _index = 5;
            _isBack = true;
            colors[_indexList[_index].x] = firstBgColor;
            colors[_indexList[_index].y] = secondBgColor;
            _index--;
          } else {
            _index = 0;
            colors = getInitColors();
          }
        } else {
          colors[_indexList[_index].x] = firstFillColor;
          colors[_indexList[_index].y] = secondFillColor;
          _index++;
        }
      }

      return colors;
    }
  }

  List<Color> getInitColors() {
    List<Color> initColorList = List(12);
    for (int i = 0; i < _indexList.length; i++) {
      var indexItem = _indexList[i];
      initColorList[indexItem.x] = firstBgColor;
      initColorList[indexItem.y] = secondBgColor;
    }
    return initColorList;
  }
}

///爆闪模式
class StrobeScript extends PreviewActionScript {
  List<Point> _indexList = [
    Point(0, 7),
    Point(3, 6),
    Point(2, 9),
    Point(10, 5),
    Point(8, 11),
    Point(4, 1)
  ];

  StrobeScript(List<int> bgColor, List<int> fgColors)
      : super(bgColors: bgColor, fgColors: fgColors);
  Color _initColor;

  @override
  List<Color> getColorList() {
    List<Color> list = [];
    for (int i = 0; i < 12; i++) {
      list.add(Color(_bgColors[0]));
    }
    if (_index == _indexList.length) {
      _index = 0;
      if (currentUseColorIndex == _fgColors.length) {
        currentUseColorIndex = 0;
      }
      _initColor = Color(_fgColors[currentUseColorIndex]);
      currentUseColorIndex++;
    }
    list[_indexList[_index].x] = _initColor;
    list[_indexList[_index].y] = _initColor;
    _index++;
    return list;
  }
}

//
// ///跳变
// class JumpScript extends PreviewActionScript {
//   JumpScript(List<int> fgColors) : super(fgColors: fgColors);
//
//   @override
//   List<Color> getColorList() {
//     List<Color> list = [];
//     if (_currentMode == 0) {
//       return WaveScript(
//         [
//           0xFFFF0000,
//         ],
//         [
//           0xFFFF0000,
//           0xFF00FF00,
//           0xFF0000FF,
//           0xFFFFFF00,
//           0xFF00FFFF,
//           0xFFFF00FF,
//         ],
//       ).getColorList();
//     } else if (_currentMode == 1) {
//       return SynchronizedBreathScript(
//         [
//           0xFFFF0000,
//           0xFF00FF00,
//           0xFF0000FF,
//           0xFFFFFF00,
//           0xFF00FFFF,
//           0xFFFF00FF,
//         ],
//       ).getColorList();
//     } else if (_currentMode == 2) {
//       return SynchronousStrobeScript(
//         [
//           0xFFFF0000,
//           0xFF00FF00,
//           0xFF0000FF,
//           0xFFFFFF00,
//           0xFF00FFFF,
//           0xFFFF00FF,
//         ],
//       ).getColorList();
//     } else if (_currentMode == 3) {
//       return SynchronousJumpScript(
//         [
//           0xAAFFFF00,
//           0xAA00FFFF,
//           0xAAFF00FF,
//           0xAAFF0000,
//           0xAA00FF00,
//           0xAA0000FF,
//         ],
//         [
//           0xFFFFFF00,
//           0xFF00FFFF,
//           0xFFFF00FF,
//           0xFFFF0000,
//           0xFF00FF00,
//           0xFF0000FF,
//         ],
//       ).getColorList();
//     }
//
//     return list;
//   }
// }
//

///7彩
class MultiScript extends PreviewActionScript{
  PreviewActionScript _currentScript;
  int _currentMode = 0;
  List<PreviewActionScript> scriptList;

  MultiScript(this.scriptList){
    _currentScript = scriptList[_currentMode];
  }

  @override
  List<Color> getColorList() {
    bool isLastItem;
    if(_currentScript.maxIndex == -1){
      isLastItem = _currentScript.index == 6;
    }else{
      isLastItem = _currentScript.index == _currentScript.maxIndex;
    }
    if(isLastItem){
      if(_currentMode == scriptList.length-1){
        _currentMode = 0;
      }else{
        _currentMode++;
      }
      _currentScript = scriptList[_currentMode];
    }

    List<Color> list = _currentScript.getColorList();

    duration = _currentScript.duration;
    transformDuration = _currentScript.transformDuration;

    return list;
  }
}

///叠加模式
class SuperimposeScript extends PreviewActionScript {
  List<Point> _indexList = [
    Point(0, 7),
    Point(3, 6),
    Point(2, 9),
    Point(10, 5),
    Point(8, 11),
    Point(4, 1)
  ];

  SuperimposeScript(List<int> fgColors) : super(fgColors: fgColors);
  Color _initColor;
  List<Color> list = List.generate(12, (index) => null);

  @override
  List<Color> getColorList() {
    if (_index == _indexList.length) {
      _index = 0;
      if (currentUseColorIndex == _fgColors.length) {
        currentUseColorIndex = 0;
      }
      _initColor = Color(_fgColors[currentUseColorIndex]);
      currentUseColorIndex++;
    }
    list[_indexList[_index].x] = _initColor;
    list[_indexList[_index].y] = _initColor;
    _index++;
    return list;
  }
}

class SingleColorFillScript extends ColorFillScript {
  SingleColorFillScript(Color bgColor, Color fillColor, {needReturn = false})
      : super(bgColor, bgColor, fillColor, fillColor, needReturn: needReturn);
}
